package fun.codedesign.yinxue.util.map;

/**
 * 〈TwoValueHashMap〉<br>
 * 〈hash存储的twoValueMap〉
 *
 * @author zengjian
 * @create 2018/10/24 20:37
 */
public class TwoValueHashMap<K, V1, V2> {

    private Entry<K, V1, V2>[] entrys;
    private int size;

    public static class Entry<K, V1, V2> {
        K key;
        V1 value1;
        V2 value2;
        Entry next;

        public Entry(K key, V1 value1, V2 value2) {
            this.key = key;
            this.value1 = value1;
            this.value2 = value2;
        }

        public V1 getValue1() {
            return value1;
        }

        public V2 getValue2() {
            return value2;
        }
    }

    public void put(K key, V1 value1, V2 value2) {
        if (size == 0) {
            initEntrys();
        }
        int index = calcHashCode(key);
        // 该数组第一个节点
        Entry forwardEntry = entrys[index];
        Entry bacKEntry = forwardEntry;
        boolean exsitKey = false;
        while (forwardEntry != null) {
            if (forwardEntry.key.equals(key)) {
                exsitKey = true;
                updateEntry(forwardEntry, value1, value2);
                break;
            }
            bacKEntry = forwardEntry;
            forwardEntry = forwardEntry.next;
        }

        if (!exsitKey) {
            bacKEntry.next = new Entry(key, value1, value2);
            size++;
        }

//        int length = entrys.length;
//        for (int i = 0; i < length; i++) {
//            // 已包含该字段key,更新value1 和 value2
//            if (entrys[i] != null && entrys[i].key.equals(key)) {
//                entrys[i].value1 = value1;
//                entrys[i].value2 = value2;
//                break;
//            } else if (entrys[i] != null && !entrys[i].key.equals(key)) {
//                if (i == entrys.length - 1) {
//                    // 2倍扩容
//                    Entry[] newEntrys = new Entry[(int) (2 * (length))];
//                    System.arraycopy(entrys, 0, newEntrys, 0, entrys.length);
//                    newEntrys[entrys.length] = new Entry<>(key, value1, value2, entrys.length);
//                    entrys = newEntrys;
//                    size++;
//                    break;
//                }
//                continue;
//            } else {
//                entrys[i] = new Entry<>(key, value1, value2, i);
//                size++;
//                break;
//            }
//        }
    }

    private void updateEntry(Entry entry, V1 value1, V2 value2) {
        entry.value1 = value1;
        entry.value2 = value2;
    }

    private int calcHashCode(K key) {
        return key.hashCode() & (entrys.length - 1);
    }

    private void initEntrys() {
        entrys = new Entry[32];
    }

    public void putFirst(K key, V1 value1) {

    }

    public void putSecond(K key, V2 value2) {

    }


    public V1 getFirst(K key) {
        for (int i = 0; i < size; i++) {
            if (entrys[i].key.equals(key)) {
                return entrys[i].value1;
            }
        }
        return null;
    }

    public V2 getSecond(K key) {
        for (int i = 0; i < size; i++) {
            if (entrys[i].key.equals(key)) {
                return entrys[i].value2;
            }
        }
        return null;
    }

    public V1 removeFirst(K key) {
        return null;
    }

    public V2 removeSecond(K key) {
        return null;
    }

    public int size() {
        return size;
    }

    public Object[] value2ToArray() {
        Object[] value2s = new Object[size];
        for (int i = 0; i < size; i++) {
            value2s[i] = get(i).getValue2();
        }
        return value2s;
    }

    public Entry get(int index) {
        return entrys[index];
    }

    public boolean containsKey(K key) {
        for (int i = 0; i < size(); i++) {
            if (key.equals(entrys[i].key)) {
                return true;
            }
        }
        return false;
    }

    public void remove(K key) {
        for (int i = 0; i < size(); i++) {
            if (key.equals(entrys[i])) {
                // 将数组往前拷贝一位，并将最后一位元素置null
                Entry oldEntry = entrys[i];
                System.arraycopy(entrys, i + 1, entrys, i, entrys.length - 1 - i);
                entrys[entrys.length - 1] = null;
                size--;
                // return oldEntry;
            }
        }
        // return null;
    }

}